using System;
using ctem.kernel.logger;
using ctem.kernel;
using MCSharp;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

namespace    ctem.kernel.adbms
{
 using System;
using MCSharp;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

[Serializable()]
public  partial class ModellerService:IModeller, IDisposable, ISerializable {

 //-------------- MCsharp functions -----------

 public ModellerService ( ) {
  mcsharp_initiate();
}

 public ModellerService ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.UnPack ( info, context, this );
   }

 public void GetObjectData ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.Pack ( info, context, this );
 }

 public void mcsharp_initiate ( ) {

  Monitor.Enter ( CommExec.Objects );
  int mcObjectNumber = CommExec.Objects.Count + 1;
  CommExec.Objects.Add ( mcObjectNumber, this );
  Monitor.Exit ( CommExec.Objects );

  CommandChannel = new MCSharp.channel ( this, mcObjectNumber, "mcsharpChannelCommandChannel" );
  mcsharpQueueInterpretate = new MCSharp.ThreadQ();

  Interpretate = new MCSharp.handler ( this, mcObjectNumber, "mcsharpHandlerInterpretate" );
  ResultChannel = new MCSharp.channel ( this, mcObjectNumber, "mcsharpChannelResultChannel" );
  mcsharpQueueGetResult = new MCSharp.ThreadQ();

  GetResult = new MCSharp.handler ( this, mcObjectNumber, "mcsharpHandlerGetResult" );
 }

static ModellerService modeller ;

 ModelManager model_manager ;

 Interpreter interpreter ;

 MainLogger main_logger = new MainLogger( )  ;

 private  ModellerService (  string ResourceFolder )  {

   mcsharp_initiate();

    if ( !MCSharp.Session.Init( )   )
   throw new Exception( "Íå ìîãó èíèöèàëèçèðîâàòü MC#."  )  ;
 
  main_logger.Initialize( ResourceFolder + "\\LoggerManager.fw.config"  , ResourceFolder  )  ;
 model_manager  = new ModelManager( main_logger.GetLogger( "Model Manager"  )  , main_logger.GetLogger( "Model Executor"  )  )  ;
 interpreter  = new Interpreter( model_manager  , main_logger  )  ;
 FireInterpreter( )  ;
 ILogger ADBMS_logger = main_logger.GetLogger( "ADBMS"  )  ;

  ADBMS_logger.WriteMessage( MessagePriority.Debug  , "ADBMS OK"  )  ;


 }

  private class McsharpPrivateClassFireInterpreter {

   ModellerService parent;

   public McsharpPrivateClassFireInterpreter ( ModellerService parent
              ) {
    this.parent = parent;
   }

   public void run() {

   MCSharp.ThreadManager.SetThreadAffinityMask();

    parent.mcsharpFireInterpreterBody (  );

   }
  }

  private void mcsharpFireInterpreterBody (

              )
 {
   bool result = true  ;

  while ( result  == true   )
  {
   result  = (bool)Interpretate  .Get(new object[]{ } )
;
 }

  Dispose( )  ;
 }




   void FireInterpreter (  ) {
   McsharpPrivateClassFireInterpreter prclassobject = new McsharpPrivateClassFireInterpreter ( this );
   ThreadStart tstart = new ThreadStart ( prclassobject.run );
   ( new Thread ( tstart ) ).Start();
  }
public static  IModeller QueryModellerService (  string ResourceFolder )   {
   if ( modeller  == null   )
   modeller  = new ModellerService( ResourceFolder  )  ;

  return modeller  ;
  }
public  void AsyncSendCommand (  string command )   {
   CommandChannel.Send ( new object[] {  command  , null   } )
  ;
 }

 //-------------Channel declarations-----------------

  public MCSharp.channel CommandChannel;

 //-------------Handler declaration-----------------

    public MCSharp.handler Interpretate;


 //-------------Queues------------------------------

 [NonSerialized] private MCSharp.ThreadQ mcsharpQueueInterpretate;


 //-------------Masks--------------------------------

 private const int mcsharp_mask_Interpretate = 1 << 0;
 private const int mcsharp_mask_CommandChannel = 1 << 1;
 private const int mcsharp_mask_InterpretateCommandChannel =
            mcsharp_mask_Interpretate
          | mcsharp_mask_CommandChannel;
 [NonSerialized] private MCSharp.BitMask mcsharpBitMaskInterpretateCommandChannel = new MCSharp.BitMask();

 private void scanInterpretateCommandChannel () {
  if ( mcsharpBitMaskInterpretateCommandChannel.match
        ( mcsharp_mask_InterpretateCommandChannel ) )
   mcsharpQueueInterpretate.wakeup();
 }


[OneWay]
public void mcsharpChannelCommandChannel (  string command,  channel  resultChannel )  {
   lock ( mcsharpQueueInterpretate ) {
    CommandChannel.Enqueue ( new object [] { command, resultChannel } );
    if ( ! mcsharpBitMaskInterpretateCommandChannel.match
          ( mcsharp_mask_CommandChannel ) )   {
     mcsharpBitMaskInterpretateCommandChannel.set ( mcsharp_mask_CommandChannel );
     scanInterpretateCommandChannel ();
    }
   }
 }

 public bool mcsharpHandlerInterpretate (  )   {
  Monitor.Enter ( mcsharpQueueInterpretate );
  if ( ! mcsharpBitMaskInterpretateCommandChannel.match ( mcsharp_mask_Interpretate ) ) goto now;
  later:
   mcsharpQueueInterpretate.yield ( mcsharpQueueInterpretate );
   if ( mcsharpQueueInterpretate.empty )
    mcsharpBitMaskInterpretateCommandChannel.clear ( mcsharp_mask_Interpretate );
  now:
   if ( mcsharpBitMaskInterpretateCommandChannel.match ( 
    mcsharp_mask_CommandChannel ) )   {
    object[] oCommandChannel = ( object[] ) CommandChannel.Dequeue();
    string command = ( string ) oCommandChannel [ 0 ];
    channel  resultChannel = ( channel  ) oCommandChannel [ 1 ];
    if ( CommandChannel.Count == 0 )
         mcsharpBitMaskInterpretateCommandChannel.clear ( mcsharp_mask_CommandChannel );
    scanInterpretateCommandChannel ();
    Monitor.Exit ( mcsharpQueueInterpretate );
     {
   bool result = true  ;

  lock ( interpreter   )  {
   result  = interpreter.Interpret( command  , resultChannel  )  ;
 }
 return result  ;
  }
   }
   else {
    mcsharpBitMaskInterpretateCommandChannel.set ( mcsharp_mask_Interpretate );
    goto later;
  }

 }
 object SyncSendCommand (  string command )   {
   CommandChannel.Send ( new object[] {  command  , ResultChannel   } )
  ;
 return GetResult  .Get(new object[]{ } )
;
  }

 //-------------Channel declarations-----------------

  public MCSharp.channel ResultChannel;

 //-------------Handler declaration-----------------

    public MCSharp.handler GetResult;


 //-------------Queues------------------------------

 [NonSerialized] private MCSharp.ThreadQ mcsharpQueueGetResult;


 //-------------Masks--------------------------------

 private const int mcsharp_mask_GetResult = 1 << 0;
 private const int mcsharp_mask_ResultChannel = 1 << 1;
 private const int mcsharp_mask_GetResultResultChannel =
            mcsharp_mask_GetResult
          | mcsharp_mask_ResultChannel;
 [NonSerialized] private MCSharp.BitMask mcsharpBitMaskGetResultResultChannel = new MCSharp.BitMask();

 private void scanGetResultResultChannel () {
  if ( mcsharpBitMaskGetResultResultChannel.match
        ( mcsharp_mask_GetResultResultChannel ) )
   mcsharpQueueGetResult.wakeup();
 }


[OneWay]
public void mcsharpChannelResultChannel (  object result )  {
   lock ( mcsharpQueueGetResult ) {
    ResultChannel.Enqueue ( new object [] { result } );
    if ( ! mcsharpBitMaskGetResultResultChannel.match
          ( mcsharp_mask_ResultChannel ) )   {
     mcsharpBitMaskGetResultResultChannel.set ( mcsharp_mask_ResultChannel );
     scanGetResultResultChannel ();
    }
   }
 }

 public object mcsharpHandlerGetResult (  )   {
  Monitor.Enter ( mcsharpQueueGetResult );
  if ( ! mcsharpBitMaskGetResultResultChannel.match ( mcsharp_mask_GetResult ) ) goto now;
  later:
   mcsharpQueueGetResult.yield ( mcsharpQueueGetResult );
   if ( mcsharpQueueGetResult.empty )
    mcsharpBitMaskGetResultResultChannel.clear ( mcsharp_mask_GetResult );
  now:
   if ( mcsharpBitMaskGetResultResultChannel.match ( 
    mcsharp_mask_ResultChannel ) )   {
    object[] oResultChannel = ( object[] ) ResultChannel.Dequeue();
    object result = ( object ) oResultChannel [ 0 ];
    if ( ResultChannel.Count == 0 )
         mcsharpBitMaskGetResultResultChannel.clear ( mcsharp_mask_ResultChannel );
    scanGetResultResultChannel ();
    Monitor.Exit ( mcsharpQueueGetResult );
     {
   return result  ;
  }
   }
   else {
    mcsharpBitMaskGetResultResultChannel.set ( mcsharp_mask_GetResult );
    goto later;
  }

 }
public  void Dispose (  )   {
   main_logger.Destroy( )  ;
 MCSharp.Session.FinalizeIt( )  ;
 }
}


}